def BUILD_AUTH_SERVICE = false
def BUILD_CONFIG = false
def BUILD_FRONTEND_CLIENT = false
def BUILD_GATEWAY = false
def BUILD_PRODUCT_SERVICE = false
def BUILD_REGISTRY = false
def BUILD_REVIEW_SERVICE = false

pipeline {
    agent any

    tools {
        maven 'maven-3.6.3'
        jdk 'openjdk-8'
    }

    environment {
        DOCKER_CREDENTIALS = credentials('paragon-docker-zyx42')
    }

    stages {
        stage('Validation') {
            steps {
                dir('auth-service') {
                    script {
                        // Using the git command to check the difference between previous successful commit.
                        // ${GIT_PREVIOUS_SUCCESSFUL_COMMIT} is an environment variable comes with GIT Jenkins plugin
                        // There is a drawback though, if it is the first time you are running this job, this variable is not available and fails the build
                        // For the first time you have to use ${env.GIT_COMMIT} itself at both places to pass the build. A hack but worth it for future builds.
                        if (env.GIT_COMMIT != null) {
                            strCount = sh(returnStdout: true, script: "git diff --name-only ${env.GIT_COMMIT} ${GIT_PREVIOUS_SUCCESSFUL_COMMIT} | grep auth-service | wc -l").trim()
                            if (strCount == "0") {
                                echo "Skipping build of auth-service, no files updated"
                            } else {
                                echo "Changes found in the auth-service"
                                BUILD_AUTH_SERVICE = true
                            }
                        } else {
                            echo "Apparently you're running this job for the first time, thus env.GIT_COMMIT is not available and validation will be skipped"
                            BUILD_AUTH_SERVICE = true
                        }
                    }
                }
                dir('config') {
                    script {
                        if (env.GIT_COMMIT != null) {
                            strCount = sh(returnStdout: true, script: "git diff --name-only ${env.GIT_COMMIT} ${GIT_PREVIOUS_SUCCESSFUL_COMMIT} | grep config | wc -l").trim()
                            if (strCount == "0") {
                                echo "Skipping build of config, no files updated"
                            } else {
                                echo "Changes found in the config"
                                BUILD_CONFIG = true
                            }
                        } else {
                            echo "Apparently first run, thus env.GIT_COMMIT is not available and validation will be skipped"
                            BUILD_CONFIG = true
                        }
                    }
                }
                dir('frontend-client') {
                    script {
                        if (env.GIT_COMMIT != null) {
                            strCount = sh(returnStdout: true, script: "git diff --name-only ${env.GIT_COMMIT} ${GIT_PREVIOUS_SUCCESSFUL_COMMIT} | grep frontend-client | wc -l").trim()
                            if (strCount == "0") {
                                echo "Skipping build of frontend-client, no files updated"
                            } else {
                                echo "Changes found in the frontend-client"
                                BUILD_FRONTEND_CLIENT = true
                            }
                        } else {
                            echo "Apparently first run, thus env.GIT_COMMIT is not available and validation will be skipped"
                            BUILD_FRONTEND_CLIENT = true
                        }
                    }
                }
                dir('gateway') {
                    script {
                        if (env.GIT_COMMIT != null) {
                            strCount = sh(returnStdout: true, script: "git diff --name-only ${env.GIT_COMMIT} ${GIT_PREVIOUS_SUCCESSFUL_COMMIT} | grep gateway | wc -l").trim()
                            if (strCount == "0") {
                                echo "Skipping build of gateway, no files updated"
                            } else {
                                echo "Changes found in the gateway"
                                BUILD_GATEWAY = true
                            }
                        } else {
                            echo "Apparently first run, thus env.GIT_COMMIT is not available and validation will be skipped"
                            BUILD_GATEWAY = true
                        }
                    }
                }
                dir('product-service') {
                    script {
                        if (env.GIT_COMMIT != null) {
                            strCount = sh(returnStdout: true, script: "git diff --name-only ${env.GIT_COMMIT} ${GIT_PREVIOUS_SUCCESSFUL_COMMIT} | grep product-service | wc -l").trim()
                            if (strCount == "0") {
                                echo "Skipping build of product-service, no files updated"
                            } else {
                                echo "Changes found in the product-service"
                                BUILD_PRODUCT_SERVICE = true
                            }
                        } else {
                            echo "Apparently first run, thus env.GIT_COMMIT is not available and validation will be skipped"
                            BUILD_PRODUCT_SERVICE = true
                        }
                    }
                }
                dir('registry') {
                    script {
                        if (env.GIT_COMMIT != null) {
                            strCount = sh(returnStdout: true, script: "git diff --name-only ${env.GIT_COMMIT} ${GIT_PREVIOUS_SUCCESSFUL_COMMIT} | grep registry | wc -l").trim()
                            if (strCount == "0") {
                                echo "Skipping build of registry, no files updated"
                            } else {
                                echo "Changes found in the registry"
                                BUILD_REGISTRY = true
                            }
                        } else {
                            echo "Apparently first run, thus env.GIT_COMMIT is not available and validation will be skipped"
                            BUILD_REGISTRY = true
                        }
                    }
                }
                dir('review-service') {
                    script {
                        if (env.GIT_COMMIT != null) {
                            strCount = sh(returnStdout: true, script: "git diff --name-only ${env.GIT_COMMIT} ${GIT_PREVIOUS_SUCCESSFUL_COMMIT} | grep review-service | wc -l").trim()
                            if (strCount == "0") {
                                echo "Skipping build of review-service, no files updated"
                            } else {
                                echo "Changes found in the review-service"
                                BUILD_REVIEW_SERVICE = true
                            }
                        } else {
                            echo "Apparently first run, thus env.GIT_COMMIT is not available and validation will be skipped"
                            BUILD_REVIEW_SERVICE = true
                        }
                    }
                }
            }
        }
        stage('auth-service') {
            when {
                expression {
                    BUILD_AUTH_SERVICE
                }
            }
            stages {
                stage('Build') {
                    steps {
                        dir('auth-service') {
                            sh "mvn clean package -DskipTests"
                        }
                    }
                }
                stage('Make container') {
                    steps {
                        dir('auth-service') {
                            sh "docker build -t zyx42/paragon-auth-service:latest ."
                        }
                    }
                }
            }
            post {
                success {
                    sh 'docker login -u "\"$DOCKER_CREDENTIALS_USR\"" -p "\"$DOCKER_CREDENTIALS_PSW\""'
                    sh "docker push zyx42/paragon-auth-service:latest"
                }
            }
        }

        stage('config') {
            when {
                expression {
                    BUILD_CONFIG
                }
            }
            stages {
                stage('Build') {
                    steps {
                        dir('config') {
                            sh "mvn clean package -DskipTests"
                        }
                    }
                }
                stage('Make container') {
                    steps {
                        dir('config') {
                            sh "docker build -t zyx42/paragon-config:latest ."
                        }
                    }
                }
            }
            post {
                success {
                    sh 'docker login -u "\"$DOCKER_CREDENTIALS_USR\"" -p "\"$DOCKER_CREDENTIALS_PSW\""'
                    sh "docker push zyx42/paragon-config:latest"
                }
            }
        }

        stage('frontend-client') {
            when {
                expression {
                    BUILD_FRONTEND_CLIENT
                }
            }
            stages {
                stage('Build') {
                    steps {
                        dir('frontend-client') {
                            sh "npm install"
                            sh "ng build --prod"
                        }
                    }
                }
                stage('Make container') {
                    steps {
                        dir('frontend-client') {
                            sh "docker build -t zyx42/paragon-frontend-client:latest ."
                        }
                    }
                }
            }
            post {
                success {
                    sh 'docker login -u "\"$DOCKER_CREDENTIALS_USR\"" -p "\"$DOCKER_CREDENTIALS_PSW\""'
                    sh "docker push zyx42/paragon-frontend-client:latest"
                }
            }
        }

        stage('gateway') {
            when {
                expression {
                    BUILD_GATEWAY
                }
            }
            stages {
                stage('Build') {
                    steps {
                        dir('gateway') {
                            sh "mvn clean package -DskipTests"
                        }
                    }
                }
                stage('Make container') {
                    steps {
                        dir('gateway') {
                            sh "docker build -t zyx42/paragon-gateway:latest ."
                        }
                    }
                }
            }
            post {
                success {
                    sh 'docker login -u "\"$DOCKER_CREDENTIALS_USR\"" -p "\"$DOCKER_CREDENTIALS_PSW\""'
                    sh "docker push zyx42/paragon-gateway:latest"
                }
            }
        }

        stage('product-service') {
            when {
                expression {
                    BUILD_PRODUCT_SERVICE
                }
            }
            stages {
                stage('Build') {
                    steps {
                        dir('product-service') {
                            sh "mvn clean package -DskipTests"
                        }
                    }
                }
                stage('Make container') {
                    steps {
                        dir('product-service') {
                            sh "docker build -t zyx42/paragon-product-service:latest ."
                        }
                    }
                }
            }
            post {
                success {
                    sh 'docker login -u "\"$DOCKER_CREDENTIALS_USR\"" -p "\"$DOCKER_CREDENTIALS_PSW\""'
                    sh "docker push zyx42/paragon-product-service:latest"
                }
            }
        }

        stage('registry') {
            when {
                expression {
                    BUILD_REGISTRY
                }
            }
            stages {
                stage('Build') {
                    steps {
                        dir('registry') {
                            sh "mvn clean package -DskipTests"
                        }
                    }
                }
                stage('Make container') {
                    steps {
                        dir('registry') {
                            sh "docker build -t zyx42/paragon-registry:latest ."
                        }
                    }
                }
            }
            post {
                success {
                    sh 'docker login -u "\"$DOCKER_CREDENTIALS_USR\"" -p "\"$DOCKER_CREDENTIALS_PSW\""'
                    sh "docker push zyx42/paragon-registry:latest"
                }
            }
        }

        stage('review-service') {
            when {
                expression {
                    BUILD_REVIEW_SERVICE
                }
            }
            stages {
                stage('Build') {
                    steps {
                        dir('review-service') {
                            sh "mvn clean package -DskipTests"
                        }
                    }
                }
                stage('Make container') {
                    steps {
                        dir('review-service') {
                            sh "docker build -t zyx42/paragon-review-service:latest ."
                        }
                    }
                }
            }
            post {
                success {
                    sh 'docker login -u "\"$DOCKER_CREDENTIALS_USR\"" -p "\"$DOCKER_CREDENTIALS_PSW\""'
                    sh "docker push zyx42/paragon-review-service:latest"
                }
            }
        }
    }
}
